﻿using HY.Common;
using HY.Model;
using Newtonsoft.Json;
using SqlSugar;
using System.ComponentModel.DataAnnotations;
using System.Reflection;

namespace HY.Service
{
    /// <summary>
    /// 静态数据上下文类，如需注入使用，去除static关键字后注入即可
    /// </summary>
    public class DbContext
    {
        private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        static DbContext()
        {
            db.DbMaintenance.CreateDatabase();
            if (!db.DbMaintenance.IsAnyTable("sys_resource"))
            {
                db.CodeFirst.InitTables(typeof(SysResource));
                db.Insertable(new SysResource() { ParentId = 0, ResourceName="系统管理", ResourceIcon = "layui-icon layui-icon-set", ResourceType = 1, SortNumber = 99 }).ExecuteCommand();
                db.Insertable(new SysResource() { ParentId = 1, ResourceName = "资源管理", ResourceIcon = "layui-icon layui-icon-set", ResourceType = 1, SortNumber = 10, ResourceUrl = "SysResource/Index" }).ExecuteCommand();
                db.Insertable(new SysResource() { ParentId = 1, ResourceName = "角色管理", ResourceIcon = "layui-icon layui-icon-set", ResourceType = 1, SortNumber = 20, ResourceUrl = "SysRole/Index" }).ExecuteCommand();
                db.Insertable(new SysResource() { ParentId = 1, ResourceName = "用户管理", ResourceIcon = "layui-icon layui-icon-user", ResourceType = 1, SortNumber = 30, ResourceUrl = "SysUser/Index" }).ExecuteCommand();
                db.Insertable(new SysResource() { ParentId = 1, ResourceName = "用户管理-重置密码", ResourceIcon = "", ResourceType = 2, SortNumber = 31, ResourceUrl = "SysUser/PasswordReset" }).ExecuteCommand();
                db.Insertable(new SysResource() { ParentId = 0, ResourceName = "区域测试", ResourceIcon = "layui-icon layui-icon-list", ResourceType = 1, SortNumber = 10, ResourceUrl = "Test/AreaTest/Index" }).ExecuteCommand();
            }
            if (!db.DbMaintenance.IsAnyTable("sys_role"))
            {
                db.CodeFirst.InitTables(typeof(SysRole));
                db.Insertable(new SysRole() { RoleName="管理员", ResourceIds="1,2,3,4" }).ExecuteCommand();
            }
            if (!db.DbMaintenance.IsAnyTable("sys_user"))
            {
                db.CodeFirst.InitTables(typeof(SysUser));
                db.Insertable(new SysUser() { UserName = "admin", RoleId = 0, RoleName = "超级管理员", Password = StringHelper.MD5Encrypt("123456") }).ExecuteCommand();
                db.Insertable(new SysUser() { UserName = "gaoqh", RoleId = 1, RoleName = "管理员", Password = StringHelper.MD5Encrypt("123456") }).ExecuteCommand();
            }
            if (!db.DbMaintenance.IsAnyTable("sys_log"))
            {
                db.CodeFirst.InitTables(typeof(SysLog));
            }
        }

        public readonly static SqlSugarScope db = new(new ConnectionConfig()
        {
            DbType = SqlSugar.DbType.SqlServer,
            InitKeyType = InitKeyType.Attribute,
            IsAutoCloseConnection = true,
            ConnectionString = AppSetting.GetValue("ConnectionStrings:DefaultConnection"),
            ConfigureExternalServices = new ConfigureExternalServices
            {
                EntityService = (c, p) =>
                {
                    // int?  decimal?这种 isnullable=true
                    if (c.PropertyType.IsGenericType && c.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                    {
                        p.IsNullable = true;
                    }
                    else if (c.PropertyType == typeof(string) && c.GetCustomAttribute<RequiredAttribute>() == null)
                    { //string类型如果没有Required isnullable=true
                        p.IsNullable = true;
                    }
                }
            }
        },
        db =>
        {
            db.Aop.OnExecutingChangeSql = (sql, pars) =>
            {
                foreach (SugarParameter p in pars)
                {
                    if (p.Value?.GetType() == typeof(string))
                    {
                        p.Value = p.Value.ToString()!.Trim();
                    }
                }
                //logger.Debug("sql:{0},params:{1}", sql, JsonConvert.SerializeObject(pars.ToDictionary(t => t.ParameterName, t => t.Value)));
                return new KeyValuePair<string, SugarParameter[]>(sql, pars);
            };
            db.Aop.OnLogExecuting = (sql, pars) =>
            {
                logger.Debug("sql:{0},params:{1}", sql, JsonConvert.SerializeObject(pars.ToDictionary(t => t.ParameterName, t => t.Value)));
            };
        });
        public static ISimpleClient<SysUser> SysUser => db.GetSimpleClient<SysUser>();
        public static ISimpleClient<SysRole> SysRole => db.GetSimpleClient<SysRole>();
        public static ISimpleClient<SysResource> SysResource => db.GetSimpleClient<SysResource>();
        public static ISimpleClient<SysLog> SysLog => db.GetSimpleClient<SysLog>();
    }
}
